<!-- 表单组件 -->
<template>
  <div class="form">
    <el-form :model="data"
             :rules="rules"
             ref="form"
             :label-width="labelWidth"
             class="demo-ruleForm"
             v-bind="{...formConfig}"
             label-position="left"
             :inline="inline">
      <div class="form_group">
        <template v-for="(val, key) in formData">
          <el-form-item v-if="val.display != 'none' && (val.is_sumbit || true)"
                        :label="val.label"
                        :prop="val.name"
                        :key="key"
                        :style="{maxWidth: val.width ? `${val.width}` : '320px',minWidth:val.width ? `${val.width}` : '320px'}">
            <!-- <el-row type="flex"> -->
            <el-col :span="val.span ? val.span:20">
              <!-- 输入框 -->
              <el-input v-if="val.type === 'input' && 'datatype' in val == false"
                        v-model="data[val.name]"
                        :placeholder="val.placeholder || '请输入'"
                        v-bind="{...val.config}"></el-input>
              <el-input v-if="val.type === 'input' && 'datatype' in val && val.datatype == 'number'"
                        v-model.number="data[val.name]"
                        :placeholder="val.placeholder || '请输入'"
                        v-bind="{...val.config}"></el-input>
              <!-- 联想输入框 -->
              <el-autocomplete v-if="val.type === 'autocomplete'"
                               class="inline-input"
                               v-model="data[val.name]"
                               :fetch-suggestions="($event,$cb) => querySearch($event,$cb,val.groups)"
                               :placeholder="val.placeholder || '请输入'"></el-autocomplete>
            </el-col>
            <!-- 选择框 -->
            <el-select v-if="val.type === 'select'"
                       v-model="data[val.name]"
                       :placeholder="val.placeholder || '请选择'"
                       v-bind="{...val.config}"
                       @change="($event) => selectChange($event,val)">
              <el-option v-for="(item, key) in val.groups"
                         :key="key"
                         v-bind="{...item}"></el-option>
            </el-select>
            <!-- 日期选择器 -->
            <el-date-picker v-if="val.type === 'date_picker'"
                            type="date"
                            :placeholder="val.placeholder || '选择日期'"
                            v-model="data[val.name]"
                            style="width: 100%;"
                            v-bind="{...val.config}"></el-date-picker>
            <!-- 时间选择器 -->
            <el-time-picker v-if="val.type === 'time_picker'"
                            :placeholder="val.placeholder || '选择时间'"
                            v-model="data[val.name]"
                            style="width: 100%;"
                            v-bind="{...val.config}"></el-time-picker>
            <!-- 时间日期选择器 -->
            <el-date-picker v-if="val.type === 'date_time_picker'"
                            v-model="data[val.name]"
                            v-bind="{...val.config}"
                            range-separator="至"
                            start-placeholder="开始日期"
                            end-placeholder="结束日期">
            </el-date-picker>
            <!-- 时间范围选择器 -->
            <el-date-picker v-if="val.type === 'date_time_range'"
                            v-model="data[val.name]"
                            :picker-options="pickerOptions"
                            v-bind="{...val.config}"
                            type="datetimerange"
                            range-separator="至"
                            start-placeholder="开始日期"
                            end-placeholder="结束日期">
            </el-date-picker>
            <!-- 切换按钮 -->
            <el-switch v-if="val.type === 'switch'"
                       active-value="1"
                       inactive-value="0"
                       v-model="data[val.name]"
                       v-bind="{...val.config}"></el-switch>
            <!-- 多选框 -->
            <el-checkbox-group v-if="val.type === 'checkbox'"
                               v-model="data[val.name]"
                               v-bind="{...val.config}">
              <el-checkbox v-for="(item, key) in val.groups"
                           :key="key"
                           v-bind="{...item}"></el-checkbox>
            </el-checkbox-group>
            <!-- 单选框 -->
            <el-radio-group v-if="val.type === 'radio'"
                            v-model="data[val.name]"
                            v-bind="{...val.config}"
                            @change="(item) => radioChange(item,val)">
              <el-radio v-for="(item, key) in val.groups"
                        :key="key"
                        v-bind="{...item}"></el-radio>
            </el-radio-group>
            <!-- 文本域 -->
            <el-input v-if="val.type === 'textarea'"
                      type="textarea"
                      :placeholder="val.placeholder || '请输入'"
                      v-model="data[val.name]"
                      v-bind="{...val.config}"></el-input>
            <!-- 文件上传 -->
            <Upload v-if="val.type === 'data_upload'"
                    type="data_upload"
                    :ref="val.name"
                    :upload_name="val.name"
                    @onSuccess="onSuccess"
                    @onRemove="onRemove"
                    @onPreview="onPreview"
                    :config="val.config"
                    :message="val.message" />
            <!-- 图片上传 -->
            <Upload v-if="val.type === 'image_upload'"
                    type="image_upload"
                    :ref="val.name"
                    :upload_name="val.name"
                    :config="val.config"
                    @onImgSuccess="onImgSuccess"
                    @onImgRemove="onImgRemove"
                    :message="val.message" />
            <!-- 富文本 -->
            <Editor :ref="'editor' + val.name"
                    v-if="val.type == 'editor'"
                    :default_value="val.value"></Editor>
            <!-- 文本 -->
            <span v-if="val.type == 'text'">{{val.value}}</span>
            <!-- 自定义增减表单 -->
            <editForm ref="editForm"
                      @submit="editSumbit"
                      v-if="val.type == 'editForm'"
                      :form_name="val.name"
                      :default_value="val.value"
                      @editSumbit="editSumbit"
                      :formData="val.config.formData"></editForm>
            <!-- 选择表格 -->
            <select-table :ref="'select_table' + val.name"
                          v-if="val.type == 'select_table'"
                          :formData="val.config.formData"
                          :columnData="val.config.columnData"
                          :url="val.config.url"
                          :name="val.name"
                          @selectTableHandler="selectTableHandler">
            </select-table>
            <!-- 组件按钮 -->
            <el-col :span="4">
              <slot name="form-icon"
                    :data="val"></slot>
            </el-col>
            <!-- </el-row> -->
          </el-form-item>
        </template>
      </div>

      <el-form-item class="form_footer">
        <el-button type="primary"
                   @click="submitForm('form')">{{sumbitName}}</el-button>
        <el-button v-if="showReset"
                   @click="resetForm('form')">{{resetName}}</el-button>
        <slot name="button"></slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import Upload from "@/components/common/upload";
export default {
  data () {
    return {
      data: {},
      rules: {},
      pickerOptions: {
          shortcuts: [{
            text: '最近一周',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近一个月',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近三个月',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit('pick', [start, end]);
            }
          }]
        },
    };
  },
  created () {
    this.createForm();
  },
  props: {
    // 表单配置
    formConfig: {
      type: Object
    },
    // 表单数据
    /**
     * 数据格式(以文本框为例)
     * [{
          name: "name",//表单元素名称
          label: "姓名",//标题
          value: "",//默认值
          type: "input",//表单类型
          span:"12",//表单长度，详情参考element的栅格布局
          // 可根据需要添加属性
          // 表单规则，详情参考element组件文档
          rules: [
            { required: true, message: "请输入活动名称", trigger: "blur" },
            { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
            { required: true, message: "请选择活动名称", trigger: "blur" },
            { type: 'number', message: '年龄必须为数字值'},
          ]
        }]
     */
    formData: {
      type: Array,
      required: true
    },
    // 标题宽度
    labelWidth: {
      type: String,
      default: () => {
        return "100px";
      }
    },
    inline: {
      type: Boolean
    },
    // 提交按钮名称
    sumbitName: {
      type: String,
      default: () => {
        return "提交";
      }
    },
    // 显示重置按钮
    showReset: {
      type: Boolean,
      default: () => {
        return true;
      }
    },
    // 重置按钮名称
    resetName: {
      type: String,
      default: () => {
        return "重置";
      }
    },
    // 是否在提交后重置页码信息
    is_sumbit_reset: {
      type: Boolean,
      default: () => {
        return false;
      }
    },
  },
  components: { Upload },
  methods: {
    // 初始化表单数据
    createForm () {
      let data = {},
        rules = {};
      for (var idx in this.formData) {
        if ('datatype' in this.formData[idx] && this.formData[idx].datatype == 'number') {
          data[this.formData[idx].name] = Number(this.formData[idx].value);
        } else {
          data[this.formData[idx].name] = this.formData[idx].value;
        }
        if ("rules" in this.formData[idx]) {
          rules[this.formData[idx].name] = this.formData[idx].rules;
        }
      }
      this.data = this.$utils.deepClone(data);
      this.rules = this.$utils.deepClone(rules);
    },
    editSumbit (data) {
      console.log(data)
    },
    // 自定义表单元素提交
    editSumbit (e) {
      console.log(e)
      this.data[e.name] = e.data;
    },
    // 处理表单元素
    submitForm (formName, bool = false) {
      let count = 0;
      let formData = {
        valid: false,
        data: {},
        is_page: bool,
        is_sumbit_reset: this.is_sumbit_reset
      };
      // if(this.is_sumbit_reset){
      //   formData.is_page = false
      // }
      this.formData.forEach(item => {
        if (item.type == 'editor') {
          formData.data[item.name] = this.$refs[`editor${item.name}`][0].value || '';
          this.data[item.name] = this.$refs[`editor${item.name}`][0].value || '';
        }
      })
      for (var i in this.formData) {
        if (this.formData[i].type == 'editForm') {
          this.$refs.editForm[0].submitForm('edit');
          count = 1;
          setTimeout(() => {
            this.$refs[formName].validate(valid => {
              if (valid) {
                formData.valid = valid;
                formData.data = this.data;
                this.$emit("submit", formData);
              } else {
                throw "error submit!!";
              }
            });
          }, 500);
          break;
        }
      }

      if (count == 0) {
        this.$refs[formName].validate(valid => {
          if (valid) {
            formData.valid = valid;
            formData.data = this.data;
            this.$emit("submit", formData);
          } else {
            throw "error submit!!";
          }
        });
      }
    },
    // 重置表单
    resetForm (formName) {
      let fd = this.formData;
      this.$refs[formName].resetFields();
      this.data = {};
      for (var idx in fd) {
        if (fd[idx].type === "data_upload" || fd[idx].type === "image_upload") {
          this.$refs[fd[idx].name][0].$children[0].clearFiles();
        }
        if(fd[idx].type === "editor"){
          console.log(this.$refs[`editor${fd[idx].name}`])
          this.$refs[`editor${fd[idx].name}`][0].value = ''
        }
      }
      this.$emit("reset", true);
    },
    // 处理单选框展示子级组件
    radioChange (val, data) {
      if (data.isChild) {
        for (var idx in data.groups) {
          if (data.groups[idx].label === val) {
            this.radioHandler(data.groups[idx].childList, data);
          }
        }
      }
    },
    radioHandler (arr, data) {
      for (var i in data.groups) {
        let cl = data.groups[i].childList;
        for (var j in cl) {
          for (var k in this.formData) {
            if (cl[j] === this.formData[k].name) {
              this.formData[k].isShow = false;
            }
          }
        }
      }

      for (var idx in arr) {
        for (var idx2 in this.formData) {
          if (arr[idx] === this.formData[idx2].name) {
            this.formData[idx2].isShow = true;
            console.log(this.formData[idx2]);
          }
        }
      }
    },
    // 处理选择框事件
    selectChange (e, val) {
      if ('sel_rule' in val) {
        // 处理联选
        let rule = val.sel_rule;
        let sr = val.sel_arr;
        let show_arr = []
        let count = 0;
        for (let i in rule) {
          if (rule[i].id == e) {
            show_arr = rule[i].show_arr;
            count = 1;
            if ('change_arr' in rule[i]) {
              this.selHandler(rule[i].change_arr);
            }
          }
        }
        let fd = this.formData;
        for (let i in fd) {
          for (let j in sr) {
            if (fd[i].name == sr[j]) {
              this.data[sr[j]] = '';
              fd[i].display = 'none';
            }
          }
        }
        for (let i in fd) {
          for (let j in show_arr) {
            if (fd[i].name == show_arr[j]) {
              fd[i].display = true;
            }
          }
        }

      }
    },
    selHandler (change_arr) {
      let fd = this.formData;
      for (var i in change_arr) {
        this.$req.get(change_arr[i].url).then(res => {
          let data = res.data;
          for (var j in fd) {
            if (fd[j].name == change_arr[i].name) {
              console.log(fd[j].groups)
              fd[j].groups = [];
              fd[j].value = ""
              for (var k in data) {
                fd[j].groups.push({
                  label: data[k][change_arr[i].labelKey],
                  value: data[k][change_arr[i].valueKey]
                })
              }
            }
          }
        })
      }
    },
    // 处理多选表格提交
    selectTableHandler (e) {
      console.log(e);
      let data = e.data,
        name = e.name,
        fd = this.formData,
        res = '';

      for (var i in this.formData) {
        if (fd[i].name == e.name) {
          switch (fd[i].config.rule) {
            case 'string':
              for (var j in data) {
                res += `${data[j][fd[i].config.valueKey]},`;
              }
              res = res.substr(0, res.length - 1);
              break;
            case 'array':
              break;
          }
        }
      }
      this.data[e.name] = res;
    },
    // 清空所有多选表格
    clearAllSelection () {
      for (var i in this.formData) {
        if (this.formData[i].type == 'select_table') {
          this.$refs[`select_table${this.formData[i].name}`][0].clearSelection();
        }
      }
    },
    // 接受文件上传成功
    onSuccess (e) {
      console.log("onSuccess", e);
      this.data[e.upload_name] = e.fileList;
    },
    // 接受文件移除
    onRemove (e) {
      console.log("onRemove", e);
      this.data[e.upload_name] = e.fileList;
    },
    // 接受文件预览
    onPreview (e) {
      console.log("onPreview", e);
      this.data[e.upload_name] = e.fileList;
    },
    // 接受图片上传成功
    onImgSuccess (e) {
      // console.log("onImgSuccess", e);
      console.log('fileList===>', e.fileList)
      if (e.fileList.length > 1 || e.is_multiple) {
        let arr = [];
        for (var i in e.fileList) {
          if ('response' in e.fileList[i] == true) {
            arr.push(e.fileList[i].response.data.img_url)
          } else {
            arr.push(e.fileList[i].url)
          }
        }
        console.log(arr)
        // if(this.data[e.upload_name].length > 0){
        //   this.data[e.upload_name] = this.data[e.upload_name].concat(arr)
        // }else{
        // }
        this.data[e.upload_name] = arr;

      } else {
        this.data[e.upload_name] = e.response.data.img_url;
      }
      console.log('upload_name=====>', this.data[e.upload_name])
    },
    // 接受图片移除
    onImgRemove (e) {
      console.log("onImgRemove", e);
      if (e.fileList.length > 1 || e.is_multiple) {
        let arr = [];
        for (var i in e.fileList) {
          if ('response' in e.fileList[i] == true) {
            arr.push(e.fileList[i].response.data.img_url)
          } else {
            arr.push(e.fileList[i].url)
          }
        }
        console.log(arr)
        // if(this.data[e.upload_name].length > 0){
        //   this.data[e.upload_name] = this.data[e.upload_name].concat(arr)
        // }else{
        // }
        this.data[e.upload_name] = arr;
      } else {
        this.data[e.upload_name] = e.file.url;
      }
    },
    querySearch (queryString, cb, groups) {
      var results = queryString ? groups.filter(this.createFilter(queryString)) : groups;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    createFilter (queryString) {
      return (groups) => {
        return (groups.label.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
      };
    },
  },
  watch: {
    formData (val) {
      console.log(val);
      this.createForm();
    }
  }
};
</script>
<style lang='scss'>
.demo-ruleForm {
  .form_group {
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      display: flex;
      margin-bottom: 20px;
      .el-form-item__label {
        min-width: 100px;
      }
    }
  }
  .form_footer {
    margin-top: 10px !important;
    margin-bottom: 30px;
    .el-form-item__content {
      margin: 0 !important;
    }
  }
}
</style>